import type {
  CreateCrudOptionsProps,
  CreateCrudOptionsRet,
  CrudExpose,
  FormScopeContext,
  FormWrapperContext,
} from '@fast-crud/fast-crud';

import type { Ref } from 'vue';

import type { Undefinedable } from '@vben/types';

import type { FormRulesExt } from '#/api';
import type { DefDictModel } from '#/api/devOperation/system/model/defDictModel';

import { h, ref } from 'vue';

import { $t } from '@vben/locales';

import { DefDictApi } from '#/api/devOperation/system/defDict';
import { ActionEnum } from '#/enums/commonEnum';
import { useMessage } from '#/hooks/web/useMessage';
import {
  createdTimeColumn,
  deleteButton,
  indexColumn,
  STATE_CONSTANT_DICT,
  transformQuery,
} from '#/plugins/fast-crud/common';

interface ContextRef {
  subTableRef: Ref<Undefinedable<any>>;
}

export function createCrudOptions(
  props: CreateCrudOptionsProps<DefDictModel.DefDictResultVO, ContextRef>,
): CreateCrudOptionsRet<DefDictModel.DefDictResultVO> {
  const selectedRowKeys = ref<string[]>([]);
  const { notification, createMessage } = useMessage();
  return {
    crudOptions: {
      request: {
        pageRequest: DefDictApi.pageRequest,
        addRequest: DefDictApi.addRequest,
        editRequest: DefDictApi.editRequest,
        delRequest: DefDictApi.delRequest,
        infoRequest: DefDictApi.infoRequest,
        transformQuery: (query) => {
          const tq = transformQuery(query);
          tq.sort = 'createdTime';
          tq.order = 'desc';
          return tq;
        },
      },

      form: {
        col: { span: 12 },
        beforeSubmit: async (
          context: FormScopeContext<DefDictModel.DefDictResultVO>,
        ) => {
          const errMap = await props.context.subTableRef.value.fullValidate();
          if (errMap) {
            let msgStr = '';
            Object.values(errMap).forEach((errList: any) => {
              errList.forEach((params: any) => {
                const { rowIndex, column, rules } = params;
                rules.forEach((rule: any) => {
                  msgStr += `第 ${rowIndex + 1} 行 ${column.title} 校验错误：${rule.message} <br/>`;
                });
              });
            });
            notification.warn({
              message: '校验失败',
              description: () => {
                return h('div', { innerHTML: msgStr }, []);
              },
              duration: 5,
            });
            return false;
          }

          const { insertRecords, removeRecords, updateRecords } =
            props.context.subTableRef.value.getRecordset();
          context.form.insertList = insertRecords;
          context.form.updateList = updateRecords;
          context.form.deleteList = removeRecords.map((item: any) => item.id);
        },
        wrapper: {
          onOpened: (
            context: FormWrapperContext<DefDictModel.DefDictResultVO>,
          ) => {
            if (ActionEnum.ADD === context.mode) {
              props.context.subTableRef.value.load(context.mode);
            } else {
              props.context.subTableRef.value.load(
                context.mode,
                context.form.id,
              );
            }
          },
        },
      },
      actionbar: {
        buttons: {
          ...deleteButton({
            crudExpose: props.crudExpose,
            selectedRowKeys,
            removeFn: DefDictApi.remove,
          }),
        },
      },
      table: {
        striped: true,
        rowKey: 'id',
        rowSelection: {
          type: 'checkbox',
          selectedRowKeys,
          onChange: (changed: string[]) => {
            selectedRowKeys.value = changed;
          },
        },
      },
      rowHandle: {
        width: '100px',
        buttons: {
          view: { show: false },
          copy: {
            click: async ({ row }) => {
              await DefDictApi.copy(row.id);
              createMessage.success($t('common.tips.copySuccess'));
              props.crudExpose.doRefresh();
            },
          },
        },
      },
      columns: {
        ...indexColumn(props.crudExpose),
        key: {
          title: $t('devOperation.system.defDict.key'),
          type: ['text', 'copyable'],
          search: { show: true },
        },
        name: {
          title: $t('devOperation.system.defDict.name'),
          type: 'text',
          search: { show: true },
        },
        state: {
          title: $t('devOperation.system.defDict.state'),
          type: 'dict-radio',
          dict: STATE_CONSTANT_DICT,
          search: { show: true, component: { mode: 'multiple' } },
          addForm: { value: true },
          column: { width: 80 },
        },
        sortValue: {
          title: $t('devOperation.system.defDict.sortValue'),
          type: 'number',
          column: {
            show: false,
          },
        },
        remark: {
          title: $t('devOperation.system.defDict.remark'),
          type: 'textarea',
          column: { show: false },
        },
        ...createdTimeColumn({}),
      },
    },
  };
}

export const frontRules = (
  _crudExpose: CrudExpose,
  _mode: ActionEnum,
): FormRulesExt => {
  return {};
};
